local Module_MQTT = {}


-- _G.Module_GETDATA = require("Module_GETDATA")
local dp = Module_GETDATA.data_point


--根据自己的服务器修改以下参数
local tlink_mqtt_server = "1883.dtuip.com"
local tlink_mqtt_port = 1883

local mqtt_host = tlink_mqtt_server
local mqtt_port = tlink_mqtt_port
local mqtt_isssl = false
local client_id = "LTECAT1GPS123456"

local user_name = "runwuxingnong"
local password = "king@123"

local clientid_prefix = "LTECAT1GPS"      -- TLINK 4G阀门控制器设备SN前10个byte, 应该与IMEI末尾6六位拼接组成16为tlink sn号


local pub_topic = ""                      -- topic to publish
local sub_topic = ""                      -- topic to sbuscribe

local mqttc = nil                         -- mqtt client object

local mqtt_disconnect_counter = 10        -- mqtt disconnect event counter, down to 0 will reset mcu


---------------------------------------------------------------

json_data = {
    sensorDatas = {
        [1] = {flag = "solar_v", value = 0},
        [2] = {flag = "bat_v", value = 4.2},
        [3] = {flag = "rssi", value = 28},
        [4] = {flag = "loc", lat = 0, lng = 0},                 --基站定位
        [5] = {flag = "loc_rtk", lat = 0, lng = 0},             --rtk定位
        [6] = {flag = "cpu_temp", value = 0},
        -- [11] = {flag = "iccid", str = "X"},
        -- [12] = {flag = "qruid", str = "x"},
        -- [13] = {flag = "imei", str = "x"},
        -- [14] = {flag = "FW", str = VERSION}
    }
}

-------------------------------local functions------------------------------------------

--[[
功能  :等待 socket ready，获取4G模组 IMEI ICCID后形成TLINK设备ID
参数  ：


返回值：无
]]
local function get_lte_module_info( )

    log.info("XJAU.CS.ANDYWANG", "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
    log.info("IN_get_lte_module_info", "新疆农业大学780EP-4G总线阀 FW = ", VERSION)

    local module_imei =  mobile.imei()                                        --- 获得 4G模组IMEI序列号
    dp.imei =  module_imei                             --- 获得 4G模组IMEI序列号

    log.info("IN_get_lte_module_info", "imei = ", module_imei)

    -- if QRUID == DB_V_QRUID_INIT  then
    --     client_id = clientid_prefix..dp.imei:sub(-6,-1)
    --     for i = 1,100 do
    --         log.info("IN_get_lte_module_info", "请写入二维码")
    --         sys.wait(1000)
    --     end

    --     log.info("IN_get_lte_module_info", "二维码绑定超时,请重试 ")
    -- elseif QRUID:startsWith("RWEVAL")  then
    --     client_id =  QRUID                                   --- 用IMEI的后6个byte拼接成TLINK 的 SN号
    -- end

    client_id = clientid_prefix..dp.imei:sub(-6,-1)

    dp.clientid = client_id                              --- 用IMEI拼接成TLINK 的 SN号
    log.info("IN_get_lte_module_info", "VALVE SN = ", dp.clientid)

    dp.iccid =  mobile.iccid()                             -- SIM 卡 ICCID最后7位
    log.info("IN_get_lte_module_info", "iccid  = ", dp.iccid)
    log.info("XJAU.CS.ANDYWANG", "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")

end

--[[
功能  ：
参数  ：
返回值：无
]]
local function refresh_jsondata()
    -- [1] = {flag = "solar_v", value = 0},
    -- [2] = {flag = "bat_v", value = 4.2},
    -- [3] = {flag = "rssi", value = 28},
    -- [4] = {flag = "loc", lat = 0, lng = 0},                 --基站定位
    -- [5] = {flag = "loc_rtk", lat = 0, lng = 0},             --rtk定位
    -- [6] = {flag = "cpu_temp", value = 0},
    json_data.sensorDatas[1].value = dp.solar_v         -- 太阳能板电压
    json_data.sensorDatas[2].value = dp.bat_v           -- 电池电压=模组供电电压
    json_data.sensorDatas[3].value = dp.rssi            -- rssi
    json_data.sensorDatas[4].lng = dp.lng               -- 经度
    json_data.sensorDatas[4].lat = dp.lat               -- 纬度
    json_data.sensorDatas[5].lng = dp.lng_rtk               -- 经度
    json_data.sensorDatas[5].lat = dp.lat_rtk               -- 纬度
    json_data.sensorDatas[6].value  = dp.cpu_temp       -- 在水压数据点显示CPU温度
 
    -- json_data.sensorDatas[11].str = QRUID               -- 外壳QRUID 二维码ID
    -- json_data.sensorDatas[12].str = dp.iccid            -- iccid
    -- json_data.sensorDatas[13].str = dp.imei             -- imei
    -- json_data.sensorDatas[14].str = VERSION             -- 程序版本


end




--[[
功能  ：发布MQTT 数据主题，上传数据
参数  ：
返回值：返回发送成功的json报文，为后续补发做准备
]]
local function publish_data()

    refresh_jsondata()                                          -- 更新json table数据
    -- log.warn("v1,v2,v3,v4,solarvol =  ", json_data.sensorDatas[1].value,json_data.sensorDatas[2].value,
    -- json_data.sensorDatas[3].value,json_data.sensorDatas[4].value,data_point.solar_v)                  -- 四个阀门开度

    local data2pub = json.encode(json_data,"5f")
    log.warn("mqtt>>:", data2pub)                       -- 阀控器json数据包
    -- ===========================发送数据=============================
    local packageID = mqttc:publish(pub_topic, data2pub, 1) -- send to tlink mqtt server
    -- log.warn("publish_data", "pakage id =  " ,packageID)


end



--[[
功能  ：发布MQTT 数据主题，上传数据
参数  ：
返回值：返回发送成功的json报文，为后续补发做准备
]]
local function publish_heartbeat()
    local devinfo_json =  {
        sensorDatas = {
            [1] = {flag = "rssi", value = 28},
            [2] = {flag = "iccid", str = "X"},
            [3] = {flag = "qruid", str = "x"},
            [4] = {flag = "imei", str = "x"},
            [5] = {flag = "FW", str = VERSION}
        }
    }
    sys.publish("notify_valve_query", -1)
    sys.wait(3*1000)


    devinfo_json.sensorDatas[1].value = dp.rssi           -- 信号强度
    devinfo_json.sensorDatas[2].str = dp.iccid            -- sim卡 iccid
    devinfo_json.sensorDatas[3].str = QRUID               -- 外壳QRUID 二维码ID
    devinfo_json.sensorDatas[4].str = dp.imei             -- 设备IMEI
    devinfo_json.sensorDatas[5].str = VERSION             -- 程序版本

    local data2pub = json.encode(devinfo_json,"2f")
    log.info("mqtt>>:", data2pub)                       -- 阀控器json数据包
    -- ===========================发送数据=============================
    local packageID = mqttc:publish(pub_topic, data2pub, 1) -- send to tlink mqtt server
    log.info("publish_data", "pakage id =  " ,packageID)


end


local function mqtt_client_init()

    -- 下面的是mqtt的参数均可自行修改
    pub_topic = client_id                   --evalve send to mqtt topic
    sub_topic = client_id .. "/+"           --evalve receive from mqtt topic

    -- 上报: 设备 ---> 服务器
    -- 下发: 设备 <--- 服务器
    -- 可使用mqtt.x等客户端进行调试
    log.info("mqtt", "pub", pub_topic)
    log.info("mqtt", "sub", sub_topic)

    -------------------------------------
    mqttc = mqtt.create(nil, mqtt_host, mqtt_port, mqtt_isssl, ca_file)     -- create mqtt client

    if mqttc == nil then sys.publish(MSG_REBOOT)  end                                  -- mqtt lient create failed, reboot

    mqttc:auth(client_id,user_name,password)        -- client_id必填,其余选填
    -- mqttc:keepalive(240) -- 默认值240s
    mqttc:autoreconn(true, 3000)                    -- 自动重连机制

    -------------mqtt client event handler-------------
    mqttc:on(function(mqtt_client, event, data, payload)
        -- 用户自定义代码
        log.info("mqtt", "event", event, mqtt_client, data, payload)
        if event == "conack" then
            -- 联上了
            sys.publish("mqtt_conack")
            mqtt_client:subscribe(sub_topic)                            --单主题订阅
            -- mqtt_client:subscribe({[topic1]=1,[topic2]=1,[topic3]=1})--多主题订阅
        elseif event == "recv" then
            -- log.info("mqtt", "downlink", "topic:", data, "payload:", payload)
            sys.publish("msg_mqtt_cmd", data, payload)
            coroutine.resume(socketsoftdog,"feed_Main.WDT")                      -- 喂狗，类似执行了continue语句
        elseif event == "sent" then
            -- log.info("mqtt", "sent", "pkgid", data)
        elseif event == "disconnect" then
            mqtt_disconnect_counter = mqtt_disconnect_counter - 1
            log.error("mqtt_client_init", "disconnect counter: ", mqtt_disconnect_counter)
            if mqtt_disconnect_counter < 1 then
                log.error("mqtt_client_init", "disconnect reboot")
                sys.publish(MSG_REBOOT)  --重启设备
            end
        end
    end)

    -- mqttc自动处理重连, 除非自行关闭
    mqttc:connect()                     -- connect to server

    local res, _useless_ =  sys.waitUntil("mqtt_conack", NETWORK_WAIT_MAX_TIME)
    if res == false then                -- mqtt连接失败，则重启
        log.error("mqtt_client_init", "mqtt_conack message not ariive in time")
        sys.publish(MSG_REBOOT)  --重启设备
    end

end



---------- 联网协程 ---------
sys.taskInit(function()

    -- 默认都等到联网成功
    local res, _useless_ =  sys.waitUntil("IP_READY", NETWORK_WAIT_MAX_TIME)
    if res == false then                -- 超时后联网失败，则重启
        log.error("MQTT TSK", "IP_READY message not ariive in time")
        sys.publish(MSG_REBOOT)  --重启设备
    end

    get_lte_module_info()               -- get 4glte cat.1 module information

    -- 默认都等到联网成功
    sys.publish("net_ready")
end)


---------- 数据上报协程 ---------
sys.taskInit(function()
    -- 等待联网
    local ret, __useless__ = sys.waitUntil("net_ready", NETWORK_WAIT_MAX_TIME)
    if res == false then                        -- 超时后联网失败，则重启
        log.error("MQTT TSK", "net_ready message not ariive in time")
        sys.publish(MSG_REBOOT)  --重启设备
    end
    mqtt_client_init()                          -- init the mqtt client

    if mqttc and mqttc:ready() then publish_heartbeat() end  --发送第一包数据
    ----------------------------------------------------------
    while true do

        sys.waitUntil("msg_mqtt_upload", MQTT_KEEP_ALIVE_TIMEOUT/2)

        if mqttc and mqttc:ready() then
        -- local pkgid = mqttc:publish(pub_topic, data .. os.date(), qos)

            publish_data()
        else
            break
        end


    end
    mqttc:close()
    mqttc = nil
    sys.publish(MSG_REBOOT)  --重启设备
end)




return Module_MQTT
